package com.firmye.codereposboot.config.security;

import com.firmye.codereposboot.dao.UserDao;
import com.firmye.codereposboot.model.user.pojo.Resource;
import com.firmye.codereposboot.model.user.pojo.Role;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.access.SecurityConfig;
import org.springframework.security.web.FilterInvocation;
import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import org.springframework.security.web.util.matcher.RequestMatcher;

import javax.annotation.PostConstruct;
import java.util.*;

/**
 * @Author Firmye
 * @Date 2017年12月7日 上午12:56:53
 * 
 * @Description 3.自定义权限管理
 */
// @Component
public class CustomFilterInvocationSecurityMetadataSource implements FilterInvocationSecurityMetadataSource {
	
	protected Log log = LogFactory.getLog(this.getClass());
	private static Map<String, Collection<ConfigAttribute>> map = null;
	
	@Autowired
	private UserDao userDao;
	
	/**
	 * @Author firmye
	 * @Date 2017年11月14日 下午4:58:55
	 *
	 * @Description 加载权限表中所有权限以及所需要的角色
	 */
	@PostConstruct
	private void loadResourceDefine() {
		List<Role> roles = userDao.queryAllRole();
		map = new HashMap<String, Collection<ConfigAttribute>>();

		if (null != roles && roles.size() > 0) {
			for (Role r : roles) {
				
				ConfigAttribute ca = new SecurityConfig(r.getRoleName());
				List<String> paths = new ArrayList<String>();
				List<Resource> reses = new ArrayList<>();
				if(null != r.getResIds())
					reses = userDao.queryResesByIds(r.getResIds());
				for (Resource res : reses) {
					paths.add(res.getAccessUrl());
				}
				for (String url : paths) {
					if (map.containsKey(url)) {
						Collection<ConfigAttribute> cas = map.get(url);
						cas.add(ca);
						map.put(url, cas);
					} else {
						Collection<ConfigAttribute> cas = new ArrayList<ConfigAttribute>();
						cas.add(ca);
						map.put(url, cas);
					}
				}
				
			}
		}
	}

	/**
	 * @Author Firmye
	 * @Date 2017年12月7日 上午12:57:02
	 *
	 * @Description 根据URL找到相应的权限（object为URL）
	 */
	@Override
	public Collection<ConfigAttribute> getAttributes(Object object) throws IllegalArgumentException {
		FilterInvocation filterInvocation = (FilterInvocation) object;
		if (null == map) {
			loadResourceDefine();
		}
		Iterator<String> iterator = map.keySet().iterator();
		while (iterator.hasNext()) {
			String resURL = iterator.next();
			RequestMatcher requestMatcher = new AntPathRequestMatcher(resURL);
			if (requestMatcher.matches(filterInvocation.getHttpRequest())) {

				log.info("=====> Required authorities:" + map.get(resURL));
				
				return map.get(resURL);
			}
		}

		return null;
	}

	/**
	 * @Author Firmye
	 * @Date 2017年12月7日 上午12:57:02
	 *
	 * @Description 
	 */
	@Override
	public Collection<ConfigAttribute> getAllConfigAttributes() {
		return new ArrayList<ConfigAttribute>();
	}

	/**
	 * @Author Firmye
	 * @Date 2017年12月7日 上午12:57:02
	 *
	 * @Description 
	 */
	@Override
	public boolean supports(Class<?> clazz) {
		return true;
	}

}
